03. MiniFlow 架构
MiniFlow 架构
我们看看如何用 MiniFlow
实现这一图表结构。我们将使用一个 Python 类来表示普通节点。
class Node(object):
def __init__(self):
# Properties will go here!
我们知道,每个节点可能会从其他多个节点那接收输入。我们还知道,每个节点都会创建一个输出,这些输出有可能会传递给其他节点。我们添加以下两个列表:一个用于存储对传入节点的引用,另一个用于存储对传出节点的引用。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
每个节点将最终计算出一个表示输出的值。我们将 value
初始化为 None
,表示该值存在,但是尚未设定。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
# A calculated value
self.value = None
每个节点都必须能够将值向前传递,并进行反向传播(稍后会详细介绍)。暂时,我们为前向传播添加一个占位符方法。我们将稍后处理反向传播。
class Node(object):
def __init__(self, inbound_nodes=[]):
# Node(s) from which this Node receives values
self.inbound_nodes = inbound_nodes
# Node(s) to which this Node passes values
self.outbound_nodes = []
# For each inbound Node here, add this Node as an outbound Node to _that_ Node.
for n in self.inbound_nodes:
n.outbound_nodes.append(self)
# A calculated value
self.value = None
def forward(self):
"""
Forward propagation.
Compute the output value based on `inbound_nodes` and
store the result in self.value.
"""
raise NotImplemented
可以进行计算的节点
虽然 Node
定义了每个节点都具有的基本属性,但是只有 Node
的特殊子类会出现在图表中。在本次实验练习中,你将构建可以进行计算和存储值的 Node
子类。例如,考虑 Node
的 Input
子类。
class Input(Node):
def __init__(self):
# An Input node has no inbound nodes,
# so no need to pass anything to the Node instantiator.
Node.__init__(self)
# NOTE: Input node is the only node where the value
# may be passed as an argument to forward().
#
# All other node implementations should get the value
# of the previous node from self.inbound_nodes
#
# Example:
# val0 = self.inbound_nodes[0].value
def forward(self, value=None):
# Overwrite the value if one is passed in.
if value is not None:
self.value = value
与 Node
的其他子类不同,Input
子类实际上并不计算任何内容。Input
子类仅仅存储了一个 value
,例如数据特征或模型参数(权重/偏置)。
你可以明确地设置 value
,或者用 forward()
方法进行设置。该值然后会传递给神经网络的其他节点。
Add 子类
Add
是 Node
的另一个子类,实际上可以进行计算(加法)。
class Add(Node):
def __init__(self, x, y):
Node.__init__(self, [x, y])
def forward(self):
"""
You'll be writing code here in the next quiz!
"""
注意 __init__
方法 Add.__init__(self, [x, y])
的不同之处。Input
类没有传入节点,而 Add
类具有 2 个传入节点 x
和 y
,并将这两个节点的值相加。